package com.wiyun.engine.skeleton;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.content.res.AssetManager;
import android.view.MotionEvent;

import com.wiyun.engine.actions.Follow;
import com.wiyun.engine.actions.MoveTo;
import com.wiyun.engine.actions.Action.Callback;
import com.wiyun.engine.astar.AStar;
import com.wiyun.engine.astar.AStarMap;
import com.wiyun.engine.astar.AStarStep;
import com.wiyun.engine.astar.RectAStarMap;
import com.wiyun.engine.nodes.Director;
import com.wiyun.engine.nodes.INodeVirtualMethods;
import com.wiyun.engine.nodes.Layer;
import com.wiyun.engine.nodes.Scene;
import com.wiyun.engine.nodes.Sprite;
import com.wiyun.engine.nodes.Animation.IAnimationCallback;
import com.wiyun.engine.opengl.Texture2D;
import com.wiyun.engine.tmx.TMXLayer;
import com.wiyun.engine.tmx.TMXTileMap;
import com.wiyun.engine.types.WYPoint;
import com.wiyun.engine.types.WYSize;
import com.wiyun.engine.utils.ResolutionIndependent;

public class MainLayer extends Layer implements IAnimationCallback, INodeVirtualMethods  {
	TMXTileMap mMap;
	TMXLayer _blockLayer;
	public MainLayer(AssetManager am) throws IOException
	{
		m_asset=am;
		m_tile_width = ResolutionIndependent.resolveDp(TILE_WIDTH);
		m_tile_height = ResolutionIndependent.resolveDp(TILE_HEIGHT);
		m_isRunning = false;
		m_paths = null;
		CreateMap();

        //_pkScene.addChild(new PKLayer(m_asset), 0);
		try {
			CreatePlayer();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void CreateMap()
	{
		Texture2D tex11 = Texture2D.makeJPG(R.drawable.bg1_00x00);
		Texture2D tex12 = Texture2D.makeJPG(R.drawable.bg1_00x01);
		Texture2D tex13 = Texture2D.makeJPG(R.drawable.bg1_00x02);
		
		Texture2D tex21 = Texture2D.makeJPG(R.drawable.bg1_01x00);
		Texture2D tex22 = Texture2D.makeJPG(R.drawable.bg1_01x01);
		Texture2D tex23 = Texture2D.makeJPG(R.drawable.bg1_01x02);
		Texture2D textAstar = Texture2D.makePNG(R.drawable.astar);
		tex11.autoRelease();
		tex12.autoRelease();
		tex13.autoRelease();

		tex21.autoRelease();
		tex22.autoRelease();
		tex23.autoRelease();
		textAstar.autoRelease();
		mMap = TMXTileMap.make(R.raw.main_layer,tex11, tex12,tex13,
		tex21, tex22,tex23, textAstar);
		mMap.setDebugDrawObjects(true);
		//mMap.scale(1.2f);
        addChild(mMap);
        mMap.setAnchor(0, 0);
        _blockLayer = mMap.getTMXLayer("block");
        //blockLayer.setVisible(false);
        int blockHeight=_blockLayer.getLayerHeight();
        int blockWidth=_blockLayer.getLayerWidth();
        m_map = RectAStarMap.make(blockWidth, blockHeight, true);
        m_astar = AStar.make(m_map);
        _blockArray = _blockLayer.getGids();
        for(int i=0;i<blockHeight;i++)
        {
        	for(int j=0;j<blockWidth;j++)
        	{
        		if(_blockArray[(int)(i*blockWidth+j)]!=0)
        			m_map.blockTile(j, blockHeight-i-1);
        	}
        }
        setTouchEnabled(true);
	}
	
	void runPath(int x, int y) {
		m_isRunning = false;
		mPlayer.stopAllActions();
		m_findStartx = (int) (mPlayer.getPositionX() / m_tile_width);
		m_findStarty = (int) (mPlayer.getPositionY() / m_tile_height);
		if(canRunDirection(mPlayer.getPositionX(), mPlayer.getPositionY(),x,y))
			_playerAnimation.RunAnimation(mPlayer,x,y);
		else
		{
			m_paths = m_astar.findPath(m_findStartx, m_findStarty, (int) (x / m_tile_width),
					(int) (y / m_tile_height), false);
	
			if (m_paths != null && m_paths.size() > 0) {
				m_isRunning = true;
				runNextMove(x,y);
			}
			else
			{
				WYPoint point = RunDirection(mPlayer.getPositionX(), mPlayer.getPositionY(),x,y);
				_playerAnimation.RunAnimation(mPlayer, point.x, point.y);
			}
		}
		
	}

	void runNextMove(final int x, final int y) {
		if (m_paths != null && m_paths.size() > 0) {
			AStarStep step = m_paths.get(m_paths.size() - 1);

			m_paths.remove(m_paths.size() - 1);

			Callback callback = new Callback() {
				public void onStart(int actionPointer) {
				}

				public void onStop(int actionPointer) {
					if (m_isRunning) {
						if (isEndPosition(x, y)) {
							runPath(x,y);
						} else {
							runNextMove(x,y);
						}
					}
				}

				public void onUpdate(int actionPointer, float t) {
				}
			};

	     	_playerAnimation.RunAnimation(mPlayer, step.getX() * m_tile_width + m_tile_width / 2, 
					step.getY() * m_tile_height	+ m_tile_height / 2, callback);
		}
	}

	boolean isEndPosition(int x, int y) {
		if (mPlayer.getPositionX() == x
				&& mPlayer.getPositionY() == y) {
			return true;
		}
		return false;
	}
	
	double getAngle(float x,float y)
	{
		return Math.atan2(y, x);// / Math.PI * 180;
	}
	
	public boolean canRunDirection(float startX, float startY, float endX, float endY)
	{
		double angle = getAngle(endX-startX, endY-startY);
		double stepX = Math.cos(angle)*m_tile_width, stepY = Math.sin(angle)*m_tile_height;
		float x=startX, y = startY;
		boolean bfoward = startX<endX;
		while(bfoward?x<endX:x>endX)
		{
			x+=stepX;
			y+=stepY;
			boolean isBlock = m_map.isBlockedAt((int)(x/m_tile_width), (int)(y/m_tile_height));
			if(isBlock)
				return false;
		}
		return true;
	}
	public WYPoint RunDirection(float startX, float startY, float endX, float endY)
	{
		double angle = getAngle(endX-startX, endY-startY);
		float stepX = (float) (Math.cos(angle)*m_tile_width), stepY = (float) (Math.sin(angle)*m_tile_height);
		float x=startX, y = startY;
		boolean bfoward = startX<endX;
		while(bfoward?x<endX:x>endX)
		{
			x+=stepX;
			y+=stepY;
			boolean isBlock = m_map.isBlockedAt((int)(x/m_tile_width), (int)(y/m_tile_height));
			if(isBlock)
				return WYPoint.make(x-stepX,y-stepY);
		}
		return WYPoint.make(endX,endY);
	}
	
	static int TILE_WIDTH = 32;
	static int TILE_HEIGHT = 32;

	float m_tile_width;
	float m_tile_height;
	int m_findStartx,m_findStarty;
	boolean m_isRunning=false;
	AStarMap m_map;
	AStar m_astar;
	ArrayList<AStarStep> m_paths;
	int[] _blockArray;
	String role="player_nanzhanshi";
	Sprite mPlayer;
	AssetManager m_asset;
	AnimationRole _playerAnimation;
	float _speed=100;
	public void CreatePlayer() throws IOException
	{
		WYSize s = Director.getInstance().getWindowSize();
		mPlayer = Sprite.make(Texture2D.makePNG(R.drawable.a_up1));
     	mPlayer. setAnchorY(0);
		mPlayer.setPosition(400, 400);
		addChild(mPlayer);
     	mPlayer.scale(0.75f);
		//player_left_anim = LoadAnimation(role+File.separator+"run_left", 0, animDurp);
		_playerAnimation = new AnimationRole(role, 0.15f, _speed, this, m_asset); 

     	//WYPoint loc = Director.getInstance().convertToGL(400, 400);
     	//_playerAnimation.RunAnimation(mPlayer, loc.x, loc.y);
     	Follow fAction = Follow.make(mPlayer, 0, 0, (int)ResolutionIndependent.resolveDp(1536), (int)ResolutionIndependent.resolveDp(1024));
        runAction(fAction);
        fAction.autoRelease();
        Sprite newplayer=Player.make(R.raw.player1, Texture2D.makePNG(R.drawable.player1));
        newplayer.setPosition(300, 300);
        newplayer.setAnchorY(0);
        newplayer.scale(1.1f);
        addChild(newplayer);
		//IntervalAction anim = (IntervalAction)Animate.make(player_left_anim, true).autoRelease();
	}
	float mLastX,mLastY;
	int i=100;
	//PKLayer _pkLayer;
	//Scene _pkScene = Scene.make();
	@Override
    public boolean wyTouchesBegan(MotionEvent event) {
        //Director.getInstance().pushScene(_pkScene);
     	mLastX = event.getX();
     	mLastY = event.getY();
     	WYPoint loc = Director.getInstance().convertToGL(event.getX(), event.getY());
     	runPath((int)loc.x, (int)loc.y);
 		//this.getParent().
        WYSize s = Director.getInstance().getWindowSize();
     	return true;
 }
 public void RunPlayer(float x, float y)
 {
	 runPath((int)x, (int)y);
 }
 @Override
 public boolean wyTouchesMoved(MotionEvent event) {
 	// remember android event origin is not same as OpenGL
 	// you can use Director.getInstance().convertToGL(event.getX(), event.getY()) to convert it to GL coordinate
 	float x = event.getX();
 	float y = event.getY();
 	float deltaX = x - mLastX;
 	float deltaY = y - mLastY; 
 	//if(Math.abs(mLastX-x)>moveCache || Math.abs(mLastY-y)>moveCache)
	{
     	mLastX = x;
     	mLastY = y;
     	
     	//mMap.translate(deltaX, -deltaY);
	}
 	return true;
 }
	@Override
	public void jDraw() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void jOnEnter() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void jOnEnterTransitionDidFinish() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void jOnExit() {
		// TODO Auto-generated method stub
		_playerAnimation.Dispose();
	}
	@Override
	public void onAnimationEnded(int arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void onAnimationFrameChanged(int arg0, int arg1) {
		// TODO Auto-generated method stub
		
	}
}
